#include <cstdio>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

void handler(int signo)
{
    printf("我是父进程，我捕捉到 %d 号信号\n",signo);

    // 1.我有非常多的子进程，在同一时刻退出了

    // 2.我有非常多的子进程，在同一个时刻只有一部分退出了
    while(1)
    {
        pid_t ret = waitpid(-1, nullptr, WNOHANG);// 默认传0是阻塞式等待，如果只有部分进程退出则这里会阻塞式调用，不会返回main执行流。一定要设置为非阻塞式等待
        // 如果在handler方法里面，我们设置为阻塞式调用，此时其他进程要退出的话，父进程由于阻塞态是无法接收到SIGCHLD信号的，那么就会导致一大批进程变为僵尸
        if(ret == 0) break;//这一轮的子进程我已经回收完了
    }
}
void Count(int cnt)
{
    while(cnt)
    {
        printf("cnt: %2d\r",cnt--);//将数字按宽度为2，采用右对齐方式输出，若数据位数不到2位，则用空格字符进行补齐。\r是回车输入，回到首行。
        fflush(stdout);
        sleep(1);
    }
}
int main()
{
    //显示的设置对SIGCHLD进行忽略
    signal(17, handler);
    // signal(17,SIG_IGN);
    // signal(17,SIG_DFL);

    printf("我是父进程, 我的pid是:%d\n", getpid());

    pid_t id = fork();
    if(id == 0)
    {
        printf("我是子进程, pid:%d ppid:%d\n", getpid(), getppid());
        printf("我是子进程, 10s后我会给父进程发送信号\n");
        Count(10);
        exit(0);
    }

    while(true) sleep(1);

    return 0;
}
// while :; do ps axj | head -1 && ps axj | grep mysignal | grep -v grep; sleep 1; done